import { Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { UserRepository } from './user.repository';
import * as bcrypt from 'bcrypt';
import { RedisService } from 'nestjs-redis';
import { v4 as uuidV4 } from 'uuid';
import { LoginDto } from './dto/login.dto';
import { BusinessException } from '@/common/exceptions/BusinessException';
import { USER_REGISTED } from '@/common/errors/Errors';
import ErrorMessages from '@/common/errors/ErrorMessages';
import { HASH_TIMES } from '@/common/consts';
import { SysUser } from '@/entities/SysUser';

@Injectable()
export class UserService {
  constructor(private readonly userRepository: UserRepository,
              private readonly redisService: RedisService) {}

  async getUsers() {
    return this.userRepository.find();
  }

  async findUserById(id: string) {
    return this.userRepository.findOneOrFail(id);
  }

  async signIn(login: LoginDto) {
    const user = await this.userRepository.findOne({ where: [{ username: login.username }]} );
    if (!user) {
      throw new NotFoundException('未找到该用户!');
    }
    const match = await bcrypt.compare(login.password, user.password);
    if (match) {
      const token = uuidV4();
      await this.redisService.getClient().set(token, JSON.stringify(user));
      return token;
    }
    throw new UnauthorizedException('错误的账号密码!');
  }

  async signUp(login: LoginDto) {
    const result = await this.userRepository.findOne({ where: [{ username: login.username }]} );
    if (result) {
      throw new BusinessException(ErrorMessages[USER_REGISTED], USER_REGISTED);
    }
    const hashedPassword = await bcrypt.hash(login.password, HASH_TIMES);
    const user = new SysUser();
    user.username = login.username;
    user.password = hashedPassword;
    user.createTime = new Date();
    const savedUser = await this.userRepository.save(user);
    // return savedUser;
    return true;
  }

  async findOneByToken(token: string) {
    const userString = await this.redisService.getClient().get(token);
    console.log(userString);
    if (!userString) { return null; }
    try {
      const user = JSON.parse(userString) as SysUser;
      console.log(user);
      return user;
    } catch (e) {
      return null;
    }
  }
}
